package idao

import (
	"fmt"

	"gitee.com/bitwormhole/weixin-applet-backend/app/classes/wxusers"
	"gitee.com/bitwormhole/weixin-applet-backend/app/data/dxo"
	"gitee.com/bitwormhole/weixin-applet-backend/app/data/entity"
	"github.com/starter-go/security/random"
	"gorm.io/gorm"
)

// WeixinUserDao ...
type WeixinUserDao struct {

	//starter:component

	_as func(wxusers.DAO) //starter:as("#")

	Agent       dxo.DatabaseAgent  //starter:inject("#")
	UUIDService random.UUIDService //starter:inject("#")

}

func (inst *WeixinUserDao) _impl() wxusers.DAO {
	return inst
}

func (inst *WeixinUserDao) model() *entity.WeixinAppletUser {
	return &entity.WeixinAppletUser{}
}

func (inst *WeixinUserDao) modellist() []*entity.WeixinAppletUser {
	return make([]*entity.WeixinAppletUser, 0)
}

func (inst *WeixinUserDao) makeResult(item *entity.WeixinAppletUser, res *gorm.DB) (*entity.WeixinAppletUser, error) {
	err := res.Error
	rows := res.RowsAffected
	if err != nil {
		return nil, err
	}
	if rows != 1 {
		return nil, fmt.Errorf("db(result).RowsAffected  is %d", rows)
	}
	if item == nil {
		return nil, fmt.Errorf("the result entity is nil")
	}
	return item, nil
}

// Find ...
func (inst *WeixinUserDao) Find(db *gorm.DB, id dxo.WeixinAppletUserID) (*entity.WeixinAppletUser, error) {
	db = inst.Agent.DB(db)
	item := inst.model()
	res := db.First(item, id)
	return inst.makeResult(item, res)
}

// FindByOpenID ...
func (inst *WeixinUserDao) FindByOpenID(db *gorm.DB, openid string) (*entity.WeixinAppletUser, error) {
	mo := inst.model()
	db = inst.Agent.DB(db)
	res := db.Where("open_id = ?", openid).First(mo)
	return inst.makeResult(mo, res)
}

// ContainOpenID ...
func (inst *WeixinUserDao) ContainOpenID(db *gorm.DB, openid string) (bool, error) {
	db = inst.Agent.DB(db)
	mo := inst.model()
	var count int64
	res := db.Model(mo).Where("open_id = ?", openid).Count(&count)
	err := res.Error
	if err != nil {
		return false, err
	}
	return (count > 0), nil
}

// Insert ...
func (inst *WeixinUserDao) Insert(db *gorm.DB, o *entity.WeixinAppletUser) (*entity.WeixinAppletUser, error) {

	o.ID = 0
	o.UUID = inst.UUIDService.Build().Class("entity.WeixinAppletUser").Generate()

	db = inst.Agent.DB(db)
	res := db.Create(o)
	return inst.makeResult(o, res)
}

// Update ...
func (inst *WeixinUserDao) Update(db *gorm.DB, id dxo.WeixinAppletUserID, updater func(*entity.WeixinAppletUser)) (*entity.WeixinAppletUser, error) {
	m := inst.model()
	db = inst.Agent.DB(db)
	res := db.First(m, id)
	if res.Error == nil {
		updater(m)
		res = db.Save(m)
	}
	return inst.makeResult(m, res)
}

// Delete ...
func (inst *WeixinUserDao) Delete(db *gorm.DB, id dxo.WeixinAppletUserID) error {
	m := inst.model()
	db = inst.Agent.DB(db)
	res := db.Delete(m, id)
	return res.Error
}
